﻿using System;
using System.Collections.Generic;
using System.Linq;
using Medora.DataContract;
using Medora.Model.Institutions;
using Medora.Services.Utils;

namespace Medora.Services.Institutions
{
    public class ScheduleItemsService : ServiceBase<ScheduleItem, ScheduleItemFilter>, IScheduleItemsService
    {
        private IRepository<ScheduleActivity> _repoScheduleActivities;

        public ScheduleItemsService(IUow uow, IUserService userService, IFilterConstructor<ScheduleItemFilter, ScheduleItem> filterConstructor) : base(uow, userService, filterConstructor)
        {
            _repository = uow.ScheduleItems;
            _repoScheduleActivities = uow.ScheduleActivities;
        }

        public IEnumerable<ScheduleItem> Get(ScheduleItemFilter filter)
        {
            return Get(filter, "");
        }

        public IEnumerable<ScheduleItem> GetWithProvider(ScheduleItemFilter filter)
        {
            return Get(filter, "Provider");
        }
        
        private IEnumerable<ScheduleItem> Get(ScheduleItemFilter filter, string includedProperties)
        {
            IQueryable<ScheduleItem> query = _repository.Get(null, null, includedProperties).AsQueryable();

            if(filter.Deleted.HasValue)
                query = query.Where(o => o.Deleted == filter.Deleted.Value).AsQueryable();

            if (filter.ProviderId.HasValue && filter.ProviderId.Value != Guid.Empty)
                query=query.Where(o => o.ProviderId == filter.ProviderId.Value).AsQueryable();

            if (filter.PersonId.HasValue && filter.PersonId.Value != Guid.Empty)
                query = query.Where(o => o.ScheduleActivity != null && o.ScheduleActivity.PersonId == filter.PersonId.Value).AsQueryable();

            if(filter.StartDateTime.HasValue)
                query = query.Where(o => System.Data.Entity.DbFunctions.DiffMinutes(o.StartDateTime, filter.StartDateTime) == 0).AsQueryable();

            if(filter.StartDateTimeFrom.HasValue)
                query = query.Where(o => System.Data.Entity.DbFunctions.TruncateTime(filter.StartDateTimeFrom.Value)<=System.Data.Entity.DbFunctions.TruncateTime(o.StartDateTime)).AsQueryable();

            if (filter.StartDateTimeTo.HasValue)
                query = query.Where(o => System.Data.Entity.DbFunctions.TruncateTime(filter.StartDateTimeTo.Value) >= System.Data.Entity.DbFunctions.TruncateTime(o.StartDateTime)).AsQueryable();

            if (filter.OneDay.HasValue)
                query = query.Where(o => System.Data.Entity.DbFunctions.TruncateTime(filter.OneDay.Value) == System.Data.Entity.DbFunctions.TruncateTime(o.StartDateTime)).AsQueryable();
            
            return query.OrderBy(o=>o.StartDateTime).ToList();
        }

        public void SaveScheduleItemsNew(List<ScheduleItem> items)
        {
            foreach (var scheduleItem in items)
            {
                if (scheduleItem.ScheduleActivity != null)
                {
                    _repoScheduleActivities.Add(scheduleItem.ScheduleActivity);
                }
                _repository.Add(scheduleItem);
            }
            
            _uow.Commit();
        }

        public void WriteActivity(Guid id, Guid personId, Guid userId, string comments=null, string deletedReason=null, Guid? referralId =null)
        {
            var scheduleItem = GetById(id);
            if (scheduleItem.ScheduleActivityId.HasValue)
            {
                var old = scheduleItem.ScheduleActivity;
                old.Deleted = true;
                old.DeletedBy = userId;
                old.DeletedOn = DateTime.Now;
                old.DeletedReason = deletedReason;
            }

            scheduleItem.ScheduleActivity = new ScheduleActivity
            {
                CreatedBy = userId, CreatedOn = DateTime.Now, PersonId = personId, Comments = comments, ReferralId = referralId
            };

            _repository.Update(scheduleItem);
            _uow.Commit();
        }

        public void ClearActivity(Guid id, Guid userId, string deletedReason = null)
        {
            var scheduleItem = GetById(id);
            if (scheduleItem.ScheduleActivityId.HasValue)
            {
                var old = scheduleItem.ScheduleActivity;
                old.Deleted = true;
                old.DeletedBy = userId;
                old.DeletedOn = DateTime.Now;
                old.DeletedReason = deletedReason;
                scheduleItem.ScheduleActivityId = null;
                scheduleItem.ScheduleActivity = null;
                _repoScheduleActivities.Update(old);
                _repository.Update(scheduleItem);
                _uow.Commit();
            }

        }
    }
}